﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Peradigm.Framework.Configuration;
using Peradigm.Framework.Domain.Security;

using Liberty.Persistence.GrantManagement;
using Liberty.Domain.CaseManagement;
using Liberty.Domain.GrantManagement;

namespace Liberty.Application.Security
{

    [Serializable]
    public class ApproveGrantPrivilege : Privilege
    {
        #region Constants
        public const string
            KEY_GRANT = "Grant",
            KEY_USER  = "CurrentUser";

        private const string CXN_STRING_KEY = "ConnectionString";
        #endregion

        #region Event Handlers
        #endregion

        #region Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action">
        /// </param>
        /// <param name="context">
        /// </param>
        /// <returns>
        /// </returns>
        public override bool Equals( Actions action, object context )
        {
            bool areEquivalent = false;
            Dictionary<string, object> contextItems = context as Dictionary<string, object>;
            if( contextItems != null )
            {
                Grant grant = contextItems[KEY_GRANT] as Grant;
                User currentUser = contextItems[KEY_USER] as User;
                areEquivalent = this.CanApprove( grant, currentUser );
            }

            return areEquivalent;
        }
        #endregion

        #region Properties
        #endregion

        #region Private Methods
        private bool CanApprove( Grant grant, User currentUser )
        {
            GrantBroker grantBroker = new GrantBroker( this.ConnectionString );
            GrantState awaitingApproval = grantBroker.GrantStateWith( (long)GrantStateOID.AwaitingApproval );
            GrantState awaitingValidation = grantBroker.GrantStateWith( (long)GrantStateOID.AwaitingValidation );
            GrantState awaitingFundMgrValidation = grantBroker.GrantStateWith( (long)GrantStateOID.AwaitingFundMgrApproval );

            bool canApprove;
            if ( this.HasSameVolunteer( grant, currentUser ) || grant.WasApprovedBy( currentUser ) )
            {
                canApprove = false;
            }
            else
            {
                GrantState stateOfGrant = grant.Status;
                canApprove = (
                                ( stateOfGrant.Equals( awaitingApproval ) || stateOfGrant.Equals( awaitingValidation ) )
                                && currentUser.IsInRole( LibertyApplication.LIBERTY_GRANT_APPROVER )
                             )
                             ||
                             (
                                stateOfGrant.Equals( awaitingFundMgrValidation )
                                && currentUser.IsInRole( LibertyApplication.LIBERTY_FUND_MANAGER )
                             );
            }
            return canApprove;
           
            /*
            if( grant.WasApprovedBy( currentUser )
                || grant.IsDispersable()
                || this.HasSameVolunteer( grant, currentUser ) )
                return false;

            if( grant.Value < 2000 )
                // Single approver required.
                return ( grant.NumApprovals() == 0 );

            if( grant.Value < 5000 )
                // Two approvers required.
                return ( grant.NumApprovals() <= 1 );

            // If value over $5,000, one grant approver and one fund manager are required.
            return ( !grant.WasApprovedBy( LibertyApplication.LIBERTY_GRANT_APPROVER ) && currentUser.IsInRole( LibertyApplication.LIBERTY_GRANT_APPROVER ) )
                || ( !grant.WasApprovedBy( LibertyApplication.LIBERTY_FUND_MANAGER ) && currentUser.IsInRole( LibertyApplication.LIBERTY_FUND_MANAGER ) );
             * */
        }
        
        private bool HasSameVolunteer( Grant grant, User currentUser )
        {
            CaseVolunteer volunteer = grant.Case.Volunteer;
            return ( string.Compare( currentUser.FirstName, volunteer.FirstName, true ) == 0 ) &&
                   ( string.Compare( currentUser.LastName, volunteer.LastName, true ) == 0 );
        }
        #endregion

        #region Private Properties
        private string ConnectionString
        {
            get
            {
                return ApplicationConfiguration.Settings[CXN_STRING_KEY];
            }
        }
        #endregion

        #region Construction and Finalization
        public ApproveGrantPrivilege( Actions action, object context )
            : base( action, context )
        {
        }
        #endregion

        #region Data Elements
        #endregion
        
    }
}
